﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using XMK.Framework.Model.Sp;
using XMK.Framework.Model;
using XMK.Utils;
using XMK.Framework.Model.Cond;
using System.Reflection;
using XMK.Framework.DataAccess;

namespace XMK.Framework
{
    /// <summary>
    /// 接口映射管理
    /// </summary>
    public class SpManager
    {
        /// <summary>
        /// Ajax初始化缓存对象，在程序启动时调用
        /// </summary>
        public static void Init(DbProvider dbProvider)
        {
            if (File.Exists(Config.ConfigHelper.SpMappingFilePath))
            {
                SpMappingInfo spMapping = SpHelper.LoadSpMapping(Config.ConfigHelper.SpMappingFilePath);
                SpHelper.InitSpMethod(dbProvider, spMapping);
            }
        }
        /// <summary>
        /// 执行服务端事件
        /// </summary>
        /// <param name="cond">标准传入参数</param>
        /// <returns>返回结果</returns>
        public static CommonDataInfo Execute(CommonDataCond cond)
        {
            LogHelper.WriteLog(LogType.Debug, cond.ws.logId+" SpManager反射处理开始：" + cond.ws.wsId);
            DateTime startTime = DateTime.Now;
            CommonDataInfo dataInfo = new CommonDataInfo();
            dataInfo.ms = new MsInfo();

            OrderInfo order = new OrderInfo();
            order.ColName = cond.ws.sortField;
            order.Sort = cond.ws.sortRule.ToString();

            PageInfo page = new PageInfo();
            page.CurrentPage = cond.ws.curPage;
            page.PageSize = cond.ws.pageSize;

            // proc自动处理开始
            string procconn = XMK.Utils.ConfigHelper.GetAppSettingValue("ProcMappingConn");
            if (!string.IsNullOrEmpty(procconn))
            {
                DbProvider dbProvider = Config.ConfigHelper.GetDbProvider(procconn);
                try
                {
                    Dictionary<string, object> dict = (Dictionary<string, object>)cond.cond;
                    // 添加当前登录员工系统参数
                    dict.Add("$userid", cond.ws.userId);
                    object o = Biz.PorcBiz.Exec(dbProvider, cond.ws.wsId, dict, order, page);
                    if (o != null)
                    {
                        dataInfo.list = o;
                        dataInfo.ms.code = "0";
                        dataInfo.ms.msg = "成功";
                        dataInfo.ms.pageCount = page.TotalPage;
                        dataInfo.ms.totalCount = page.Records;
                        dataInfo.ms.curPage = page.CurrentPage;
                        dataInfo.ms.pageSize = page.PageSize;

                        dataInfo.ms.logId = cond.ws.logId;
                        dataInfo.ms.methodName = "auto";
                        dataInfo.ms.differTime = DateHelper.GetTimeSpanString(startTime);
                        LogHelper.WriteLog(LogType.Debug, cond.ws.logId + " SpManager反射处理结束：" + cond.ws.wsId);
                        return dataInfo;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog(LogType.Error, cond.ws.logId + " 调用方法错误：" + cond.ws.wsId + "--" + ex.ToString());
                }
            }
            // proc自动处理结束

            // 取得对应的方法
            SpMethod method = SpHelper.GetSpMethod(cond.ws.wsId);
            if (method == null)
            {
                LogHelper.WriteLog(LogType.Debug, cond.ws.logId+" SpManager反射处理结束：找不到方法->" + cond.ws.wsId);
                LogHelper.WriteLog(LogType.Error, cond.ws.logId+" 找不到方法：" + cond.ws.wsId);
                dataInfo.ms.code = "1";
                dataInfo.ms.logId = cond.ws.logId;
                dataInfo.ms.methodName = method.Method.Name;
                dataInfo.ms.msg = " 找不到方法：" + cond.ws.wsId;
                dataInfo.ms.differTime = DateHelper.GetTimeSpanString(startTime);
                return dataInfo;
            }

            object[] args = null;
            ParameterInfo[] paras = method.Method.GetParameters();

            if (paras != null && paras.Length > 0)
            {
                args = new object[paras.Length];
                for (int i = 0; i < paras.Length; i++)
                {
                    if (paras[i].Name == "userId")
                    {
                        args[i] = cond.ws.userId;
                    }
                    else if (paras[i].ParameterType == typeof(PageInfo))
                    {
                        args[i] = page;
                    }
                    else if (paras[i].ParameterType == typeof(OrderInfo))
                    {
                        args[i] = order;
                    }
                    else if (paras[i].ParameterType.FullName.StartsWith("System."))
                        args[i] = ParseHelper.Parse(cond.cond, paras[i].ParameterType);
                    else
                    {
                        args[i] = JsonHelper.FromJson(JsonHelper.ToJson(cond.cond), paras[i].ParameterType);
                    }
                }
            }

            try
            {
                // 方法调用
                dataInfo.list = method.Method.Invoke(method.DataInstance, args);
                if (dataInfo.list is ResponseInfo)
                {
                    ResponseInfo retResponse = dataInfo.list as ResponseInfo;
                    dataInfo.ms.code = retResponse.State.ToString();
                    dataInfo.ms.msg = retResponse.ErrMsg;
                    dataInfo.list = retResponse.Data;
                    if (retResponse.Page != null)
                    {
                        dataInfo.ms.pageCount = retResponse.Page.TotalPage;
                        dataInfo.ms.totalCount = retResponse.Page.Records;
                        dataInfo.ms.curPage = retResponse.Page.CurrentPage;
                        dataInfo.ms.pageSize = retResponse.Page.PageSize;
                    }
                }
                else
                {
                    dataInfo.ms.code = "0";
                    dataInfo.ms.msg = "成功";
                    dataInfo.ms.pageCount = page.TotalPage;
                    dataInfo.ms.totalCount = page.Records;
                    dataInfo.ms.curPage = page.CurrentPage;
                    dataInfo.ms.pageSize = page.PageSize;
                }
                dataInfo.ms.logId = cond.ws.logId;
                dataInfo.ms.methodName = method.Method.Name;   
                dataInfo.ms.differTime = DateHelper.GetTimeSpanString(startTime);
            }
            catch (Exception ex)
            {
                dataInfo.ms.code = "1";
                dataInfo.ms.logId = cond.ws.logId;
                dataInfo.ms.methodName = method.Method.Name;
                dataInfo.ms.msg = "异常";
                dataInfo.ms.differTime = DateHelper.GetTimeSpanString(startTime);
                LogHelper.WriteLog(LogType.Error, cond.ws.logId+" 调用方法错误：" + cond.ws.wsId + "--" + ex.ToString());
            }
            LogHelper.WriteLog(LogType.Debug, cond.ws.logId+" SpManager反射处理结束：" + cond.ws.wsId);
            return dataInfo;
        }
    }
}
